var ui = (function(){
	return {
		version:'0.1.0',
		name:'JROS Web Framework',

		//判断当前窗口对象是否是框架顶层
		//入参 w[object window] 窗口对象，可选，不提供的话默认取当前窗口
		//返回 [Boolean]
		isTop: function(w) {
			w = w || window;
			return (w.parent == w.self || ! (w.parent != w.self && w.parent.ui && w.parent.ui.name == 'JROS Web Framework'));
		},
		//获取顶层窗口对象
		//返回 [object window] 最顶层的、加载了JROS web框架的页面所在的窗口对象
		getTop:function(){
			var w = window;
			while(!ui.isTop(w)){w = w.parent;}
			return w;
		},
		//从顶层框架获取一个全局唯一的id
		//返回 [String]
		getId:function(){
			var w = ui.getTop();
			w.ui._idCount++;
			return 'id_'+w.ui._idCount;
		},
		//在主功能区中加载子页面
		//入参 url[String]
		loadPage:function(url){
			var w = ui.getTop();
			new w.JROS_LOADER({position:'absolute',className:'jros_page_loader',animType:'3',background:'#333',padding:8}).draw();
			setTimeout(function(){
				w.$('#mainframe').attr('src',url);
			},0);
		},
		//加载页面逻辑
		//入参 clsName[String] 字符串格式的页面逻辑类名
		loadPageClass:function(clsName){
			var cls = eval(clsName);
			cls.prototype = new JROS_PAGE_BASE();
			cls.prototype.constructor = cls;
			var obj = new cls();
			window['o'+clsName] = obj;
			$(function(){
				setTimeout(function(){//异步加载onbeforeload
					obj.onbeforeload();
					setTimeout(function(){//异步加载onload
						obj.onload();
						setTimeout(function(){//异步加载onafterload
							obj.onafterload();
						},0);
					},0);
				},0);
				$(window).bind('resize',{o:obj},function(ev){
					ev.data.o.onresize(ev);
				});
				$(window).bind('scroll',{o:obj},function(ev){
					ev.data.o.onscroll(ev);
				});
				$(window).bind('beforeunload',{o:obj},function(ev){
					ev.data.o.onbeforeunload(ev);
				});
				$(window).bind('unload',{o:obj},function(ev){
					ev.data.o.onunload(ev);
				});
			});
		},
		//获取页面URL参数
		//入参  str[String] 字符串格式的URL路径，可选，如不提供默认取当前页面URL
		//返回  [object] url参数键值对，key为参数名，value 为参数值
		getUrlParams:function(str){
			str = decodeURI(str||location.href);
			var idx = str.indexOf('?'),params = {},ary=[];
			if(idx !=-1){
				str = str.substring(idx+1,str.length);
				ary = str.split('&');
				for(var i=0;i<ary.length;i++){
					var _idx = ary[i].indexOf('=');
					params[ary[i].substring(0,_idx)] = ary[i].substring(_idx+1,ary[i].length);
				}
			}
			return params;
		},
		//从服务端请求数据
		//入参 ajaxParams[Object] 字符串格式的ajax请求参数，支持所有jQuery API,并额外提供：
		//			data[Array] 必选参数，请求数据，详见框架API文档
		//			localData[Boolean] 可选参数，默认为false，为true时将不再请求服务端接口，而是请求模拟数据(不支持打包批量请求)
		//			loader[Object] 可选参数，请求时绘制的动画图标，设置为false 将不绘制图标
		
		request:function(ap){
			var _errorFunc = ap.error,_completeFunc = ap.complete,_successFunc = ap.success;
			var _checkFormat = function(o){
				var obj = new Array();
				if(typeof(o)=='string'){
					obj = JSON.parse(o);
				}else{
					obj = o;
				}
				for(var i=0;i<obj.length;i++){
					obj[i].flag = (obj[i].flag == '-130011')?'1':obj[i].flag;
					obj[i].data.record1 = obj[i].data.record1||[];
					if(obj[i].meta.length=='0'){
						obj[i].meta.length = '1';
						obj[i].meta.record1 = {alllength:'0',length:'0'};
					}
				};
				return obj;
			};
			ap.url = ap.url||'../../jros/ajax2.do';
			ap.dataType = ap.dataType||'text json';
			ap.processData = false;
			ap.contentType= "application/json;charset:UTF-8";
			ap.data = ap.data||{};
			ap.type = ap.type||'POST';

			ap.error = function(jqXHR, textStatus, errorThrown){
				if(_errorFunc)_errorFunc(jqXHR, textStatus, errorThrown);
				throw new Error('AJAX Error: ' + textStatus);
			};
			ap.complete = function(jqXHR, textStatus){
				if(_completeFunc)_completeFunc(jqXHR, textStatus);
			};
			ap.success = function(rtn){
				rtn = _checkFormat(rtn);
				if(_successFunc)_successFunc(rtn);
			};
			//判断是否模拟数据
			if(ap.localData){
				ap.url = '../../JROS/localData/'+ap.data[0].code+'.json';
				ap.data = {};
				ap.type='GET';
			}
			//绘制动画
			if(ap.loader !== false){
				var loaderParam = (typeof ap.loader == 'object')?ap.loader:{position:'absolute',animType:'3',background:'#333',padding:8};
				var topWindow = loaderParam.container?window:ui.getTop();
				_loader = new topWindow.JROS_LOADER(loaderParam).draw();
			}
			ap.data = JSON.stringify(ap.data);
			$.ajax(ap);
		},
		//转义文本串，将<转义为&lt; > &gt; " &quot; ' &apos;
		text:function(str){
			str = String(str);
			var less = /</g,greater = />/g,quot = /\"/g,apos=/\'/g;
			return str.replace(less, '&lt;').replace(greater, '&gt;').replace(quot,'&quot;').replace(apos,'&aps;');
		}
	};
})();

function JROS_PAGE_BASE(){
	this._top = ui.getTop();
	this.SuperClass = this;
}
JROS_PAGE_BASE.prototype.onbeforeload = function(){
	new this._top.JROS_LOADER({position:'absolute',className:'jros_page_loader',animType:'3',background:'#333',padding:8}).draw();
};
JROS_PAGE_BASE.prototype.onload = function(){
	
}
JROS_PAGE_BASE.prototype.onafterload = function(){
	this._top.$('.jros_page_loader').remove();
};
JROS_PAGE_BASE.prototype.onbeforeunload = function(){
}
JROS_PAGE_BASE.prototype.onunload = function(){
	
}
JROS_PAGE_BASE.prototype.onresize = function(){
	
}
JROS_PAGE_BASE.prototype.onscroll = function(){
	
}

function JROS_LOADER(p){
	this.text = '';
	this.className = '';
	this.container = '#jros_float_area1';
	this.position = 'relative';
	this.background = '#fff';
	this.color = '#ccc';
	this.text_shadow = '-1px -1px #000;'
	this.left = 5;
	this.top = 5;
	this.padding = 0;
	this.margin = 0;
	this.style = '';
	this.animType = '2';
	this.modal = false;

	if(p){
		for(var prop in p)
			this[prop] = p[prop];
	}
	return this;
}
JROS_LOADER.prototype.draw = function(){
	var that = this;
	this._dom = $('<div class="jros_loader jros_corner_big '+this.className+'" '+
		'style="position:'+this.position+';'+
		'left:'+this.left+'px;'+
		'top:'+this.top+'px;'+
		'background:'+this.background+';'+
		'padding:'+this.padding+'px;'+
		'margin:'+this.margin+'px;'+
		'text-shadow:'+this.text_shadow+';'+
		'color:'+this.color+';'+this.style+'"><img src="../../img/ajaxLoader'+this.animType+'.gif" /> '+this.text+'</div>');
	$(this.container).append(this._dom);
	//setTimeout(function(){that.destroy()},10000);
	return this;
}
JROS_LOADER.prototype.destroy = function(){
	this._dom.remove();
}

function LIST(p){
	this.id = '';
	this.id_paging = '';
	this.code = '';
	this.params = {};
	this.params_ext = {};
	this.row_offset = 0;
	this.row_count = 10;
	this.alllength = 0;
	this.data = [];
	this.localData = false;
	this.loader = false;
	this._loader = null;
	this.func = {
		item:function(d){},
		complete:function(){},
		noData:function(){}
	};

	for(var prop in p)
		this[prop] = p[prop];
	return this;
}
LIST.prototype.draw = function(){
	var loaderParam = {
		text:'',
		container:'#'+this.id
	};
	if(this.loader){
		if(typeof this.loader == 'object')
			loaderParam = $.extend(loaderParam,this.loader);
		this._loader = new JROS_LOADER(loaderParam).draw();
	}
	if(this.code){
		this.requestData();
	}
	else this.processData();
	return this;
}
LIST.prototype.search = function(p){
	this.params = $.extend(this.params,p);
	this.row_offset = 0;
	this.requestData();
}
LIST.prototype.requestData = function(){
	var that = this;
	var reqParam = {
		localData:this.localData,
		data:[{
			code:this.code,
			params:this.params,
			params_ext:this.params_ext
		}],
		success:function(rtnJson){
			if(rtnJson[0].flag=='1'){
				that.data = rtnJson[0].data.record1;
				that.alllength = rtnJson[0].meta.record1.alllength;
				that.processData();
			}
		}
	};
	if(this.row_count!=0){
		reqParam.data[0].params_ext = $.extend(reqParam.data[0].params_ext,{row_offset:this.row_offset,row_count:this.row_count});
	};
	ui.request(reqParam);
};
LIST.prototype.processData = function(){
	$('#'+this.id).empty();
	$('#'+this.id_paging).empty();
	if(this.data.length == 0){
		var noDataItem = (this.func.noData)?this.func.noData():'<div style="width:100%;text-align:center;color:#999;">暂无数据,请稍后重试</div>';
		$('#'+this.id).append(noDataItem);
	}
	else this.processItem(0);
};
LIST.prototype.processItem = function(idx){
	var that = this;
	var d = this.data[idx];
	for(var prop in d)
		d[prop] = ui.text(d[prop]);
	var item = this.func.item(d,idx);
	$('#'+this.id).append(item);
	if((idx+1) == this.data.length){
		this.drawPaging();
		this.drawComplete();
	}
	else setTimeout(function(){that.processItem(idx+1);},0);
};
LIST.prototype.drawComplete = function(){
	if(this._loader)this._loader.destroy();
	if(this.func.complete)this.func.complete();
};
LIST.prototype.drawPaging = function(){
	var pageContainer = $('#'+this.id_paging).empty().addClass('jros_paging');

	if(this.row_count == 0)return false;
	if(this.code == '')this.alllength = this.data.length;

	var curPage = Math.floor(this.row_offset/this.row_count)+1;
	var allPageNum = (this.alllength%this.row_count==0)?Math.floor(this.alllength/this.row_count):Math.floor(this.alllength/this.row_count)+1;
	var pAry = [];
	if(allPageNum>=1&&allPageNum<=7){
		for(var i=1;i<=allPageNum;i++)
			pAry[pAry.length] = i;
	}
	else if(allPageNum>7){
		pAry = [curPage-2,curPage-1,curPage,curPage+1,curPage+2];
		var offsetAmt = 0;
		if(pAry[0]<0)offsetAmt = 2;
		else if(pAry[0] == 0)
			offsetAmt = 1;
		//4
		//[2,3,4,5,6]
		if(pAry[pAry.length-1]>=allPageNum+2)
			offsetAmt = -2;
		else if(pAry[pAry.length-1]>allPageNum)
			offsetAmt = -1;
		for(var i=0;i<pAry.length;i++)pAry[i] += offsetAmt;

		if(pAry[0]>=3)
			pAry.unshift(1,'...');
		else if(pAry[0]>=2)
			pAry.unshift(1);
		if(pAry[pAry.length-1]<allPageNum)
			pAry.push('...',allPageNum)
	}

	if(pAry.length>0){
		var btn_prev = $('<div class="jros_paging_btn jros_paging_btn_prev jros_inline_block">上一页</div>');
		var btn_next = $('<div class="jros_paging_btn jros_paging_btn_next jros_inline_block">下一页</div>');
		if(curPage == 1){
			btn_prev.addClass('jros_paging_btn_disabled');
		}
		else btn_prev.bind('click',{o:this},function(ev){
			ev.data.o.prev();
		});

		if(curPage == allPageNum){
			btn_next.addClass('jros_paging_btn_disabled');
		}
		else btn_next.bind('click',{o:this},function(ev){
			ev.data.o.next();
		})
		pageContainer.append(btn_prev);
		for(var i=0;i<pAry.length;i++){
			var btn = $('<div class="jros_paging_btn jros_paging_btn_num jros_inline_block">'+pAry[i]+'</div>');
			if(pAry[i] == '...'){
				btn.addClass('jros_paging_btn_dots');
			}
			else if(pAry[i] == curPage){
				btn.addClass('jros_paging_btn_active');
			}
			else{
				btn.bind('click',{o:this},function(ev){
					ev.data.o.gotoPage($(this).text())
				})
			}
			pageContainer.append(btn);
		}
		
		pageContainer.append(btn_next);
	}
}
LIST.prototype.prev = function(){
	this.row_offset -= this.row_count;
	this.requestData();
}
LIST.prototype.next = function(){
	this.row_offset += this.row_count;
	this.requestData();
}
LIST.prototype.gotoPage = function(pn){
	this.row_offset = (pn-1)*this.row_count;
	this.requestData();
}

//常用工具类
if (typeof KGF == "undefined"){
	var KGF = {};
}    

KGF.isEmpty = function (value) {
    if (value === null || value === undefined || value === "") {
        return true;
    } else if ((value instanceof Number || typeof(value) === "number") && isNaN(value)) {
        return true;
    } else {
        return false;
    }
};

/**
 * 判断是否成年人
 */
KGF.isAdult = function (sBirthday, sServerDate) {
    var year = sServerDate.substr(0, 4);
    var month = sServerDate.substr(4, 2);
    var day = sServerDate.substr(6, 2);
    var birthyear = sBirthday.substr(0, 4);
    var birthmonth = sBirthday.substr(4, 2);
    var birthday = sBirthday.substr(6, 2);
    var flag = year - birthyear;
    return flag > 18 || ((flag == 18) && (birthmonth < month)) || ((flag == 18) && (birthmonth == month) && (birthday < day));
};

/**
 * 跳转到指定URL
 */
KGF.gotoPage = function (url) {
	window.location.href = encodeURI(url);
};

/**
 * 过滤空字符串
 */
KGF.Trim = function (sValue) {
	if(KGF.isEmpty(sValue)){
		return "";
	}
	return sValue.replace(/\s/g,"");
};

KGF.checkSeries = function (value) {
	for (var i = 0; i < value.length; i++) {
        var charpwd1 = value.charCodeAt(i);
        var charpwd2 = value.charCodeAt(i + 1);
        var charpwd3 = value.charCodeAt(i + 2);
        if (isNaN(charpwd2) || isNaN(charpwd3) || isNaN(charpwd1)) {
            return true;
        }

        if ((charpwd2 == (charpwd1 + 1) && charpwd3 == (charpwd2 + 1))
                || (charpwd2 == (charpwd1 - 1) && charpwd3 == (charpwd2 - 1))) {
            return false;
        }
    }
    return true;
};

/**
 * 格式化整型日期,仅检查位数和字符有效性，如果无效返回
 * @param date 可以是Date、int、string类型
 * @param sSplit 分隔符,默认'-','CN'表示用年月日分隔
 * @returns string
 */
KGF.fmtDate = function (date, sSplit) {
    var sDate, sY, sM, sD;
    if (date instanceof Date) {
        sY = date.getFullYear();
        sM = date.getMonth() + 1 + "";
        if (sM.length === 1) {
            sM = "0" + sM;
        }

        sD = date.getDate() + "";
        if (sD.length === 1)
            sD = "0" + sD;
    } else {
        sDate = date.toString();
        if (/^\d{8}$/.test(sDate)) {
            sY = sDate.substring(0, 4);
            sM = sDate.substring(4, 6);
            sD = sDate.substring(6, 8);
        } else
            return "-";
    }

    if (sSplit === "CN") {
        sDate = sY + "年" + sM + "月" + sD + "日";
    } else {
        if (sSplit === "" || sSplit == null) {
            sSplit = "-";
        }
        sDate = sY + sSplit + sM + sSplit + sD;
    }
    return sDate;
};

/**
 * 格式化日期为yyyyMMdd格式
 */
KGF.reDate = function (str){
    if (typeof str == "string" && str.length == 10) {
        return str.substring(0, 4) + str.substring(5, 7) + str.substring(8, 10);
    }
    return str;
};

/**
 * 将人民币金额转换为大写
 * @param fAmount
 * @returns {sring}
 */
KGF.capitalRMB = function (fAmount, sSuffix) {
    //字符长度
    function LengthB(str) {
        var p1 = new RegExp('%u..', 'g');
        var p2 = new RegExp('%.', 'g');
        return escape(str).replace(p1, '').replace(p2, '').length;
    }

    var low;
    var i, k, j, l_xx1;
    var cap = "", xx1, unit;
    var a = ("" + fAmount).replace(/(^0*)/g, "").split(".");

    var digits = "零壹贰叁肆伍陆柒捌玖";
    var units = "份 点拾佰仟万拾佰仟亿拾佰仟万拾佰仟";
    var digit;
    low = parseFloat(fAmount);
    if (isNaN(low)) {
        return "";
    }

    xx1 = Math.round(low * 100.0) + "";
    l_xx1 = xx1.length;

    for (i = 0; i < l_xx1; i++) {
        j = l_xx1 - 1 - i;
        unit = units.substr(j, 1);
        // 生成大写单位，即'..份拾...'
        k = parseInt(xx1.substr(i, 1));
        digit = digits.substr(k, 1);
        // 生成大写数字, 即'零壹贰叁...'
        cap = cap + digit + unit;
    }

    cap = cap.replace(" ", "");
    cap = cap.replace(/零拾|零佰|零仟/g, "零");
    cap = cap.replace(/零+/g, "零");
    cap = cap.replace(/零亿/g, "亿");
    cap = cap.replace(/零万/g, "万");
    cap = cap.replace(/零点/g, "点");
    cap = cap.replace(/零份/g, "份");
    cap = cap.replace(/亿万/g, "亿");
    cap = cap.replace(/^壹拾/, "拾");
    cap = cap.replace(/点份$/, "份整");
    cap = cap.replace(/份整$/, "");
    cap = cap.replace(/零$/, "");
    cap = cap.replace(/份$/, "");
    if (a.length > 1 && LengthB(a[1]) > 2) {
        cap = '小数点位数不应超过2位';
        return cap;
    }
    if (a.length > 1 && LengthB(a[0]) == 0 && a[1].charAt(0) != '0') {
        cap = cap.replace("", "零点");
    }
    if (a.length > 1 && LengthB(a[0]) == 0 && a[1].charAt(0) == '0') {
        cap = cap.replace("", "零点零");
    }
    if (cap != "" || cap.length > 0) {
        cap = cap + sSuffix;
    }
    return cap;
};
/**
 * 格式化数字
 * @param fData 待格式的数字
 * @param sFormat 格式化掩码，支持：#，0.等字符，可选，则默认KGC.GO_AmountFmt：
 *          ‘#’一位数字，如果是数字末尾且是0则不显示，‘，’分位标志，‘0’一位数字，‘.’小数点，例1234567.1204格式化如下：
 *          #,###（#,###.#0）     1,234,567      #,###.0#            1,234,567.12
 *          #,###.##            1,234,567.12   #,###.0##        1,234,567.12
 *          #,###.00            1,234,567.12
 */
KGF.fmtNumber = function (fData, sFormat) {
    var arrTemp;
    var sInt, sFloat, sFmt,sSign;
    var fmtInt = "", fmtFloat = "";
    sSign = fData >= 0 ? "" : "-";
    fData = Math.abs(fData);
    var sData = fData.toString();
    if (arguments.length == 1) {
        sFormat = "#,##0.00"; // 系统默认金额格式化掩码
    }
    arrTemp = sFormat.match(/[\#\,0\.]+/);
    if (arrTemp != null) {
        sFmt = arrTemp[0];
    } else {
        sFmt = "#,##0.00";
    }
    var reDecimal = /\./;
    if (reDecimal.test(sFmt)) {
        arrTemp = sFmt.split(".");
        fmtInt = arrTemp[0];
        fmtFloat = arrTemp[1];
    } else {
        fmtInt = sFmt;
    }

    if (reDecimal.test(sData)) {
        if (fmtFloat != "") {
            arrTemp = sData.split(".");
            var iPow10 = Math.pow(10, fmtFloat.length);
            var fTemp = Math.round(parseFloat("0." + arrTemp[1]) * iPow10) / iPow10;
            sInt = (Math.floor(fData) + Math.floor(fTemp)).toString();
            if (fTemp == 0 || fTemp == 1)
                sFloat = "0";
            else
                sFloat = fTemp.toString().split(".")[1];
        } else {
            sInt = Math.round(fData).toString();
            sFloat = "";
        }
    } else {
        sInt = sData;
        sFloat = "";
    }

    if (fmtInt != "") {
        var iCommaLen = null;
        var iZeroCount = fmtInt.match(/0*$/)[0].length;
        if (/,/g.test(fmtInt)) {
            iCommaLen = fmtInt.match(/,[^,]*/)[0].length - 1;
        }
        var reg = new RegExp("(\\d{" + iCommaLen + "})", "g");
        if (sInt.length < iZeroCount) {
            sInt = new Array(iZeroCount + 1).join("0") + sInt;
            sInt = sInt.substr(sInt.length - iZeroCount, iZeroCount);
        }
        if (iCommaLen > 0) {
            var idx = sInt.length % iCommaLen;
            sInt = sInt.substr(0, idx) + sInt.substring(idx).replace(reg, ",$1");
        }
        sInt = sInt.replace(/^,/, "");
    }

    if (fmtFloat != "") {
        var iZeroCount = fmtFloat.match(/^0*/)[0].length;
        if (sFloat.length < iZeroCount) {
            sFloat = sFloat + new Array(iZeroCount + 1).join("0");
            if (fmtFloat.length > iZeroCount) {
                var sTemp1 = sFloat.substring(0, iZeroCount);
                var sTemp2 = sFloat.substring(iZeroCount, fmtFloat.length);
                sFloat = sTemp1 + sTemp2.replace(/0*$/, "");
            } else {
                sFloat = sFloat.substring(0, iZeroCount);
            }
        } else {
            sFloat = sFloat.substring(0, fmtFloat.length);
        }
    } else {
        sFloat = "";
    }

    if (sFloat == "") {
        sData = sInt;
    } else {
        sData = sInt + "." + sFloat;
    }
    if (sFormat != sFmt) {
        sData = sFormat.replace(sFmt, sData);
    }
    return sSign + sData;
};

/**
 * 申请金额、份额合并
 */
KGF.doGridAppAmountOrVol = function (o, val) {
    if (o.applicationamount != "0.00") {
        return KGF.fmtNumber(o.applicationamount, "#,###.00") + "（元）";
    } else if (o.applicationvol != "0.00") {
        return KGF.fmtNumber(o.applicationvol, "#,###.00") + "（份）";
    } else {
        return val;
    }
};

/*申请金额、份额合并*/
KGF.doGridAmountOrVol = function (o, val) {
    if (o.aData.applicationamount != "0.00") {
        return KGF.fmtNumber(o.aData.applicationamount, "#,###.00") + "（元）";
    } else if (o.aData.applicationvol != "0.00") {
        return KGF.fmtNumber(o.aData.applicationvol, "#,###.00") + "（份）";
    } else {
        return "-&nbsp;&nbsp;";
    }
};
/*确认金额、份额合并*/
KGF.doGridConAmountOrVol = function (o, val) {
    if (o.aData.confirmedamount != "0.00") {
        return KGF.fmtNumber(o.aData.confirmedamount, "#,###.00") + "（元）";
    } else if (o.aData.confirmedvol != "0.00") {
        return KGF.fmtNumber(o.aData.confirmedvol, "#,###.00") + "（份）";
    } else {
        return "-&nbsp;&nbsp;";
    }
};

/**
 * 从身份证号码中取出生日
 */
KGF.getBirthdayFormIdNo = function (sIdNo) {
    //15位号码
    if (sIdNo.length == 15)
        return "19" + sIdNo.substr(6, 6);
    //18位号码
    return sIdNo.substr(6, 8);
};

/**
 * 从身份证号码中取出性别
 */
KGF.getSexFormIdNo = function (sIdNo) {
    var key=sIdNo.substring(sIdNo.length-2,sIdNo.length-1);
    return (key%2)==0?0:1;
};

/**
 * 验证邮箱格式
 * @param str
 * @returns {boolean}
 */
KGF.validEmail = function(str) {
	var regxp = /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/;
	return regxp.test(str);
}

/**
 * 验证手机号格式
 * @param str
 * @returns {boolean}
 */
KGF.validMobile = function(str) {
	var regxp = /^1[34578]\d{9}$/;
	return regxp.test(str);
}

/**
 * 判断是否为微信浏览器
 */
KGF.checkIsWeiXin = function (){
	var ua = window.navigator.userAgent.toLowerCase();
	if(ua.match(/MicroMessenger/i) == 'micromessenger'){
		return true;
	}else{ 
		return false;
	}
};

/**
 * 简单检查输入的身份证号是否无效，有效返回false，无效返回true
 */
function isValidIDCardNo(code){
    var Errors = new Array("true",
            "身份证号码位数不对,必须是15位或者18位!",
            "身份证号码出生年月日格式不对!",
            "身份证号码校验位错误!",
            "身份证地区非法!",
            "15位身份证号码由数字组成!",
            "18位身份证号码前17位由数字组成,第18位可以是数字或者大写\"X\"!");
    if (code.length != 15 && code.length != 18) {// 身份证长度不正确
        return Errors[1];
    }
    var area = {
        11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",
        31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",
        44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",
        63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"
    };
    var Y, JYM;
    var S, M;
    var ereg;
    var idcard_array = new Array();
    idcard_array = code.split("");
    // 地区检验
    if (area[parseInt(code.substr(0, 2))] == null)
        return Errors[4];
    // 身份号码位数及格式检验
    switch (code.length) {
        case 15:
            if (!/^[0-9]{15}$/.test(code)) {
                return Errors[5];
            }
            var sBirthday = "19" + code.substr(6, 2) + "-"
                    + Number(code.substr(8, 2)) + "-"
                    + Number(code.substr(10, 2));
            var d = new Date(sBirthday.replace(/-/g, "/"));
            var flag = (sBirthday != (d.getFullYear() + "-"
                    + (d.getMonth() + 1) + "-" + d.getDate()));
            if (!flag)
                return Errors[0];
            else
                return Errors[2];
            break;
        case 18:
            if (!/^[0-9]{17}([0-9X])$/.test(code)) {
                return Errors[6];
            }

            var sBirthday = code.substr(6, 4) + "-"
                    + Number(code.substr(10, 2)) + "-"
                    + Number(code.substr(12, 2));
            var d = new Date(sBirthday.replace(/-/g, "/"));
            var flag = (sBirthday != (d.getFullYear() + "-"
                    + (d.getMonth() + 1) + "-" + d.getDate()));
            if (!flag) {// 测试出生日期的合法性
                // 计算校验位
                S = (parseInt(idcard_array[0]) + parseInt(idcard_array[10]))
                        * 7
                        + (parseInt(idcard_array[1]) + parseInt(idcard_array[11]))
                        * 9
                        + (parseInt(idcard_array[2]) + parseInt(idcard_array[12]))
                        * 10
                        + (parseInt(idcard_array[3]) + parseInt(idcard_array[13]))
                        * 5
                        + (parseInt(idcard_array[4]) + parseInt(idcard_array[14]))
                        * 8
                        + (parseInt(idcard_array[5]) + parseInt(idcard_array[15]))
                        * 4
                        + (parseInt(idcard_array[6]) + parseInt(idcard_array[16]))
                        * 2 + parseInt(idcard_array[7]) * 1
                        + parseInt(idcard_array[8]) * 6
                        + parseInt(idcard_array[9]) * 3;
                Y = S % 11;
                M = "F";
                JYM = "10X98765432";
                M = JYM.substr(Y, 1);
                // 判断校验位
                if (M == idcard_array[17])
                    return Errors[0];// 检测ID的校验位
                else
                    return Errors[3];
            } else
                return Errors[2];
            break;
        default:
            return Errors[1];
            break;
    }
};

/**
 * 获取用户是否登录
 */
KGF.getCustFlag = function (){
	var custFlag;
	$.ajax({
		url:"/getCustFlag.do",
		async : false,
		success:function(obj){
			if(obj.retCode=="0"){
				custFlag = obj.retData[0][0].belongto;
			}
		}
	});
	return custFlag;
}

/**
 * 保存页面路径日志
 * PID:页面标示(当前文件夹位置，和第几个页面组成的字符串    eg：register1.html 这个页面的pid：0102)
 * PNAME:页面title名称
 */
KGF.saveUrlLog = function (PID,PNAME){
	ui.request({
		url : "../../common/ajax.do",
        data:{code: 'saveUrlLog',params:{"PID":PID,"PNAME":PNAME}},
        type : "POST",
        success: function(obj) {
        	console.log("保存访问日志："+obj[0].prompt);
        }
	});
}


/**
 * 获取系统交易日期
 */
KGF.getBizDate = function (){
	if(sessionStorage.getItem("busidate")==undefined||sessionStorage.getItem("busidate")==''){
		ui.request({
			url : "../../common/ajax.do",
	        data:{code: 'qryBizDate',params:{}},
	        type : "POST",
			async : true,
			success: function(obj) {
	        	var result = obj[0].data.record1;
	            if(result){
	            	sessionStorage.setItem("busidate",result[0].busidate);
	            	return result[0].busidate;
	            }
	        }
		});
	}else{
		var busidate = sessionStorage.getItem("busidate");
		return busidate;
	}
};

function ListMap() {
    var sKeyName = "key";        // 索引属性名称
    var sValueName = "value";    // 默认值属性名称
    var oParent = {};            // 数据项MapItem.prototype的值（数据项对象的父类）
    var aoMap = [];              // 存放数据项对象的数组

    // 根据入参构建数据项对象的父类（合并所有数据对象的属性到父类中）
    var iBegin = null;
    var iArgLen = arguments.length;
    if (typeof(arguments[0]) == "string") {
        sKeyName = arguments[0];
        if (typeof(arguments[1]) == "string") {
            if (iArgLen > 0) {
                sValueName = arguments[1];
                iBegin = 2;
            } else
                iBegin = 1;
        }
        for (var i = iBegin; i < iArgLen; i++) {
            if (typeof(arguments[i]) == "object")
                $.extend(oParent, arguments[i]);
        }
    }
    var o = null;
    eval("o={'" + sKeyName + "':'','" + sValueName + "':''}");
    o.getKey = function () {
        return this[sKeyName];
    };
    o.getValue = function () {
        return this[sValueName];
    };
    $.extend(oParent, o);

    /**
     * 内部数据项类，该类继承于oParent
     */
    function MapItem() {
    }

    MapItem.prototype = oParent;

    /**
     * 根据索引属性的属性值查找数据项
     * @param vKey 数据项索引属性值
     * @returns 返回其索引位置，未找到返回-1
     */
    this.find = function (vKey) {
        for (var i = 0; i < aoMap.length; i++) {
            if (aoMap[i][sKeyName] == vKey)
                return i;
        }
        return -1;
    };

    /**
     * 通过数据项在数组中的索引获取映射项，如果索引越界，返回undefined
     * @param {number} iIndex 数据项索引
     * @returns {object} 数据项对象
     */
    this.items = function (iIndex) {
        if (KGF.isEmpty(iIndex)) return undefined;
        if (iIndex < aoMap.length && iIndex >= 0)
            return aoMap[iIndex];
        return undefined;
    };

    /**
     * 通过索引属性值获取该数据项的默认属性值，未找到返回undefined或defaultValue
     * @param vKey 数据项索引属性值
     * @param vDefaultValue 未找到默认返回值
     * @returns 默认属性值
     */
    this.get = function (vKey, vDefaultValue) {
        if ((!vKey) && (vKey != "")) return vDefaultValue;

        var i = this.find(vKey);
        return i >= 0 ? aoMap[i][sValueName] : vDefaultValue;
    };

    /**
     * 通过索引属性值获取该数据项的指定属性的属性，未找到返回undefined或defaultValue
     * @param vKey 数据项索引属性值
     * @param {string} sPropName 返回数据项该属性的属性值
     * @param vDefaultValue 未找到默认返回值
     * @returns 指定属性值
     */
    this.getValue = function (vKey, sPropName, vDefaultValue) {
        if ((!vKey) && (vKey != "")) return vDefaultValue;

        var i = this.find(vKey);
        if (i >= 0) {
            var item = aoMap[i];
            return item.hasOwnProperty(sPropName) ? item[sPropName] : vDefaultValue;
        } else
            return vDefaultValue;
    };
    /**
     * 通过索引属性值获取该数据项并返回，未找到返回undefined或defaultValue
     * @param vKey 数据项索引属性的属性值
     * @param vDefaultValue 未找到默认返回值
     * @returns 数据项对象
     */
    this.getItem = function (vKey, vDefaultValue) {
        if ((!vKey) && (vKey != "")) return vDefaultValue;

        var i = this.find(vKey);
        return i >= 0 ? aoMap[i] : vDefaultValue;
    };

    /**
     * 设置指定数据项默认属性的属性值，如果该数据项不存在则添加
     * @param vKey 数据项索引属性值
     * @param value 默认属性的属性值
     */
    this.set = function (vKey, value) {
        if ((!vKey) && (vKey != "")) return;

        var i = this.find(vKey);
        if (i >= 0)
            aoMap[i][sValueName] = value;
        else {
            var item = new MapItem();
            item[sKeyName] = vKey;
            item[sValueName] = value;
            aoMap.push(item);
        }
    };

    /**
     * 返回指定索引位置的数据项的索引属性值，如果索引越界，返回vDefaultValue
     * @param {number} iIndex 数据对象索引
     * @param vDefaultValue 未找到默认返回值
     * @returns 索引属性值
     */
    this.getKey = function (iIndex, vDefaultValue) {
        var o = this.items(iIndex);
        if (o) {
            return o[sKeyName];
        } else
            return vDefaultValue;
    };

    /**
     * 设置指定数据项指定属性的属性值，如果该数据项不存在则添加
     * @param vKey 数据项索引属性值
     * @param {string} sPropName 返回数据项该属性的属性值
     * @param value 属性值
     */
    this.setValue = function (vKey, sPropName, value) {
        if ((!vKey) && (vKey != "")) return;

        var i = this.find(vKey);
        if (i >= 0)
            aoMap[i][sPropName] = value;
        else {
            var item = new MapItem();
            item[sKeyName] = vKey;
            //if (oParent.hasOwnProperty(sPropName))
            item[sPropName] = value;
            aoMap.push(item);
        }
    };

    /**
     * 设置更新数据项，不存在则添加
     * @param {MapItem} o 数据项对象
     */
    this.setItem = function (o) {
        if (KGF.isEmpty(o)) return;

        // 检查该对象是否包含索引属性名称，不存在则退出
        var vKey = undefined;
        if (o.hasOwnProperty(sKeyName))
            vKey = o[sKeyName];
        if ((!vKey) && (vKey != "")) return;

        var item;
        var i = this.find(vKey);
        if (i >= 0) {
            item = aoMap[i];
        } else {
            item = new MapItem();
            aoMap.push(item);
        }
        // 赋值
        var prop = null;
        for (prop in o) {
            if (oParent.hasOwnProperty(prop)) {
                item[prop] = o[prop];
            }
        }
    };

    /**
     * 移除指定的数据项
     * @param vKey 数据项索引属性值
     */
    this.del = function (vKey) {
        if ((!vKey) && (vKey != "")) return;
        var i = this.find(vKey);
        if (i >= 0)
            aoMap.splice(i, 1);
    };

    /**
     * 返回列表中数据项的数目
     */
    this.count = function () {
        return aoMap.length;
    };

    /**
     * 将oList中的数据项添加到当前列表中，oData为ListMap类型或对象类型
     * @param {ListMap|object} oData 数据项列表
     */
    this.assigned = function (oData) {
        if (oData instanceof ListMap) {
            var iCount = oData.count();
            for (var i = 0; i < iCount; i++) {
                this.setItem(oData.items(i));
            }
        } else if (typeof(oData) === "object") {
            for (var sProp in oData) {
                this.set(sProp, oData[sProp]);
            }
        } else
            throw new Error("oData type error.");
    };

    /**
     * 解析字符串，插入到列表中，字符串格式：key1|value1;key2|value2;...
     * @param {string} sValue
     * @param {string} sSplitChar 每对key/valu之间的分隔符，可选，默认为分号(;)
     */
    this.parse = function (sValue, sSplitChar) {
        if (arguments.length == 1) {
            sSplitChar = ";";
        }
        var aItem;
        var aValue = sValue.split(sSplitChar);
        for (var i = 0; i < aValue.length; i++) {
            aItem = aValue[i].split("|");
            this.set(aItem[0], aItem[1]);
        }
    };

    /**
     * 检查数据项列表是否为空
     * @returns {boolean} false-非空，true-空
     */
    this.isEmpty = function () {
        return aoMap.length <= 0;
    };

    /**
     * 清除映射列表
     */
    this.clear = function () {
        aoMap.length = 0;
    };

    /**
     * 将列表项中的数据转换为JSON对象，转换原则：
     * 以索引属性的属性值为对象属性名，默认属性的属性值为对象属性值，
     * 将列表中的数据项对象的索引属性和默认属性转换为JSON对象
     */
    this.toJSON = function () {
        var oItem;
        var oJSON = {};
        for (var i = 0; i < this.count(); i++) {
            oItem = this.items(i);
            oJSON[oItem[sKeyName]] = oItem[sValueName];
        }
        return oJSON;
    };

    /**
     * 将列表项中的数据转换为JSON对象
     * Key加上"param."前缀
     */
    this.toParamJSON = function () {
        var oItem;
        var oJSON = {};
        for (var i = 0; i < this.count(); i++) {
            oItem = this.items(i);
            oJSON["param." + oItem[sKeyName]] = oItem[sValueName];
        }
        return oJSON;
    };

    /**
     * 以索引属性的属性值为参数名，默认属性的属性值为参数值，将列表中的数据项对象转换为URL查询字符串，
     * 返回查询串中首尾不带？和&；如果列表为空则返回空字符串""
     * @returns {string} URL查询串
     */
    this.toUrlParamStr = function () {
        var oItem;
        var sParams = "";
        var iCount = this.count();
        var sKeyName = this.getKeyName();
        var sValueName = this.getValueName();
        // 取第一个参数
        if (iCount > 0) {
            oItem = this.items(0);
            sParams = oItem[sKeyName] + "=" + oItem[sValueName];
        } else {
            return "".toString();
        }
        // 取剩余参数
        for (var i = 1; i < iCount; i++) {
            oItem = this.items(i);
            sParams += "&" + oItem[sKeyName] + "=" + oItem[sValueName];
        }
        return sParams.toString();
    };

    /**
     * 检查ListMap中的数据项对象是否有指定的属性名称
     * @param {string} sPropertyName 属性名称
     * @returns {boolean} false-不包含，true-包含
     */
    this.itemHasProperty = function (sPropertyName) {
        return (oParent.hasOwnProperty(sPropertyName));
    };

    /**
     * 返回数据项的索引属性名称
     * @returns 属性名称
     */
    this.getKeyName = function () {
        return sKeyName;
    };

    /**
     * 返回数据项的默认值的属性名称
     * @returns 属性名称
     */
    this.getValueName = function () {
        return sValueName;
    };
    
    /**
     * 返回数据项key数组
     * @returns 属性名称
     */
    this.getKeyNames = function () {
    	var keys = new Array();
    	var oItem;
    	for (var i = 0; i < this.count(); i++) {
    		oItem = this.items(i);
            keys.push(oItem[sKeyName]);
        }
        return keys;
    };
    
    /**
     * 返回数据项value数组
     * @returns 属性名称
     */
    this.getKeyValues = function () {
    	var values = new Array();
    	var oItem;
    	for (var i = 0; i < this.count(); i++) {
    		oItem = this.items(i);
    		values.push(oItem[sValueName]);
        }
        return values;
    };
}